﻿using System;
using System.Collections.Generic;
using System.Web.Helpers;
using System.Web.Mvc;
using PagedList;
using TestOnlineProject.Models.BusinessLogic;
using TestOnlineProject.Models.Entities;

namespace TestOnlineProject.Controllers
{
    [Authorize]
    public class DiscussionController : Controller
    {
        DiscussionBLO discussionBLO = new DiscussionBLO();
        SubjectBLO subjectBLO = new SubjectBLO();
        QuestionBLO questionBLO = new QuestionBLO();
        UserBLO userBLO = new UserBLO();
        ParticipantBLO participantBLO = new ParticipantBLO();

        //
        // GET: /Discussion/

        public ActionResult Index(int? page, int subjectId, string keyWord = "", int userId = 0, string status = "All")
        {
            var subject = subjectBLO.Find(subjectId);

            if (subject == null)
            {
                return HttpNotFound();
            }

            if (!HttpContext.User.IsInRole("1"))
            {
                if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name), subjectId))
                {
                    var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                    if (user == null)
                    {
                        return RedirectToAction("Error", "Account");
                    }
                    if (!user.IsActivated)
                    {
                        return RedirectToAction("Error", "Account");
                    }

                    TempData["Msg"] = "You can not access this subject. Please contact Admin to more details.";
                    return RedirectToAction("Index", "Subject");
                }
            }

            ViewBag.Subject = subject;

            var discussionModels = discussionBLO.ToList(subjectId, userId, keyWord, status);
            const int pageSize = 10;
            var pageNumber = (page ?? 1);

            ViewBag.KeyWord = keyWord;
            ViewBag.Page = page;

            if (status.Equals("My") || status.Equals("False"))
            {
                ViewBag.MyDiscussion = "True";
            }
            else
            {
                ViewBag.MyDiscussion = "False";
            }

            if (Request.IsAjaxRequest())
            {
                ViewBag.Search = "True";
                return PartialView("_List", discussionModels.ToPagedList(pageNumber, pageSize));
            }

            ViewBag.Msg = TempData["Msg"] as string;

            return View(discussionModels.ToPagedList(pageNumber, pageSize));
        }

        //
        // GET: /Discussion/Create

        public ActionResult Create(int subjectId)
        {
            var subject = subjectBLO.Find(subjectId);

            if (subject == null)
            {
                return HttpNotFound();
            }

            if (!HttpContext.User.IsInRole("1"))
            {
                if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name), subjectId))
                {
                    var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                    if (user == null)
                    {
                        return RedirectToAction("Error", "Account");
                    }
                    if (!user.IsActivated)
                    {
                        return RedirectToAction("Error", "Account");
                    }

                    TempData["Msg"] = "You can not access this subject. Please contact Admin to more details.";
                    return RedirectToAction("Index", "Subject");
                }
            }

            ViewBag.Subject = subject;

            var discussionCreateModel = new DiscussionCreateModel
                {
                    SubjectId = subjectId
                };

            return View(discussionCreateModel);
        }

        //
        // POST: /Discussion/Create

        [HttpPost, ValidateInput(false)]
        public ActionResult Create(DiscussionCreateModel discussionCreateModel)
        {
            if (ModelState.IsValid)
            {
                var result = discussionBLO.CheckingTitle(discussionCreateModel.SubjectId, discussionCreateModel.Title);
                if (result)
                {
                    var newDiscussion = discussionBLO.CreateDiscussion(discussionCreateModel.SubjectId, discussionCreateModel.Title, discussionCreateModel.Content);
                    if (newDiscussion != null)
                    {
                        return RedirectToAction("Details", new { subjectId = discussionCreateModel.SubjectId, discussionId = newDiscussion.DiscussionId });
                    }
                    ModelState.AddModelError("", "An error occurred!");
                }
                else
                {
                    ModelState.AddModelError("Duplicate", "Title has been available. Please input another title");
                }
            }

            var subject = subjectBLO.Find(discussionCreateModel.SubjectId);
            ViewBag.Subject = subject;

            return View(discussionCreateModel);
        }

        //
        // GET: /Discussion/Details

        public ActionResult Details(int discussionId, int thread = 0)
        {
            try
            {
                var discussionModel = discussionBLO.Find(discussionId, thread);


                if (discussionModel == null)
                {
                    return HttpNotFound();
                }

                if (!HttpContext.User.IsInRole("1"))
                {
                    if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name),
                                                         discussionModel.Subject.SubjectId))
                    {
                        var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                        if (user == null)
                        {
                            return RedirectToAction("Error", "Account");
                        }
                        if (!user.IsActivated)
                        {
                            return RedirectToAction("Error", "Account");
                        }

                        TempData["Msg"] = "You can not access this discussion. Please contact Admin to more details.";
                        return RedirectToAction("Index");
                    }
                    if (!discussionModel.Discussion.IsActivated)
                    {
                        TempData["Msg"] = "You can not access this discussion. Please contact Admin to more details.";
                        return RedirectToAction("Index", new { subjectId = discussionModel.Subject.SubjectId });
                    }
                }

                ViewBag.Subject = discussionModel.Subject;

                var userId = int.Parse(HttpContext.User.Identity.Name);
                ViewBag.User = userBLO.Find(userId);

                return View(discussionModel);
            }
            catch (Exception)
            {
                return HttpNotFound();
            }
        }

        //
        // POST: /Discussion/Details

        [HttpPost, ValidateInput(false)]
        public ActionResult Details(DiscussionModel discussionModel)
        {
            var discussion = discussionBLO.Find(discussionModel.Discussion.DiscussionId);

            if (discussion == null)
            {
                return HttpNotFound();
            }

            if (!discussion.IsActivated)
            {
                TempData["Msg"] = "You can not access this discussion. Please contact Admin to more details.";
                return RedirectToAction("Index", new { subjectId = discussionModel.Subject.SubjectId });
            }

            if (!HttpContext.User.IsInRole("1"))
            {
                if (!participantBLO.CheckParticipant(int.Parse(HttpContext.User.Identity.Name),
                                                     discussionModel.Subject.SubjectId))
                {
                    var user = userBLO.Find(int.Parse(HttpContext.User.Identity.Name));
                    if (user == null)
                    {
                        return RedirectToAction("Error", "Account");
                    }
                    if (!user.IsActivated)
                    {
                        return RedirectToAction("Error", "Account");
                    }

                    TempData["Msg"] = "You can not access this discussion. Please contact Admin to more details.";
                    return RedirectToAction("Index");
                }
            }

            var message = Request.Unvalidated().Form["textarea"];
            if (message != "")
            {
                // Create Reply
                var reply = discussionBLO.CreateReply(discussionModel, message);
                if (reply <= 0)
                {
                    ViewBag.Error = "The data is out of date. Create reply unsuccessful";
                }
            }
            else
            {
                ViewBag.Error = "Please input message";
            }

            // Reload page
            discussionModel = discussionBLO.Find(discussionModel.Discussion.DiscussionId, 0);
            ViewBag.Subject = discussionModel.Subject;

            var userId = int.Parse(HttpContext.User.Identity.Name);
            ViewBag.User = userBLO.Find(userId);

            return View(discussionModel);
        }

        //
        // GET: /Discussion/PopupQuestion

        public ActionResult PopupQuestion(int? page, int subjectId, string keyWord = "")
        {
            // No. list.
            var noList = new List<NoModel>();

            ViewBag.Page = page;
            ViewBag.SubjectId = subjectId;
            ViewBag.KeyWord = keyWord;

            const int pageSize = 10;
            var pageNumber = (page ?? 1);
            var questions = questionBLO.ToList(ref noList, subjectId, keyWord);

            ViewBag.Question = questions.ToPagedList(pageNumber, pageSize);
            ViewBag.NoList = noList;

            return PartialView("_Question");
        }

        //
        // GET: /Discussion/Update

        [ValidateInput(false)]
        public string Update(int discussionId, string content)
        {
            var result = discussionBLO.Modify(discussionId, content);
            if (result > 0)
            {
                return "Update discussion successful";
            }
            return "The data is out of date. Update unsuccessful";
        }

        //
        // GET: /Discussion/Delete

        public string DeleteReply(int replyId, int discussionId)
        {
            var result = discussionBLO.RemoveReply(replyId);
            if (result > 0)
            {
                return "Delete discussion successful!";
            }
            return "The data is out of date. Delete unsuccessful";
        }

        //
        // GET: /Discussion/AddQuestion

        public string AddQuestion(string ids = "")
        {
            var result = questionBLO.ConvertQuestionToString(ids);
            return result;
        }

        //
        // GET: /Discussion/Deactivate/

        [Authorize(Roles = "1")]
        public string Deactivate(string ids)
        {
            try
            {
                var result = discussionBLO.Deactivate(ids);
                if (result > 0)
                {
                    return result + " Discussion(s) has been deactivated.";
                }
                return "Website has encountered a problem. Please try again!";
            }
            catch (Exception)
            {
                return "Website has encountered a problem. Please try again!";
            }
        }

        //
        // GET: /Discussion/Activate/

        [Authorize(Roles = "1")]
        public string Activate(string ids = "")
        {
            try
            {
                var result = discussionBLO.Activate(ids);
                if (result > 0)
                {
                    return result + " Discussion(s) has been activated.";
                }
                return "Website has encountered a problem. Please try again!";
            }
            catch (Exception)
            {
                return "Website has encountered a problem. Please try again!";
            }
        }

        //
        // GET: /Discussion/Delete/

        [Authorize(Roles = "1")]
        public string Delete(string ids)
        {
            try
            {
                var result = discussionBLO.Remove(ids);
                if (result > 0)
                {
                    return result + " Discussion(s) has been deleted.";
                }
                return "Website has encountered a problem. Please try again!";
            }
            catch (Exception)
            {
                return "Website has encountered a problem. Please try again!";
            }
        }
    }
}
